#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "dhnetsdk.h"

#define IPSTR "127.0.0.1"                                               
#define PORT 5000                                                              
#define BUFSIZE 4096

static BOOL SDKInitFlag = FALSE;
static LLONG g_lLoginHandle = 0;
static LLONG g_LRealLoadHandle = 0;
static LLONG g_LRealLoadHandle1 = 0;
static char g_szDevIp[32] = "112.80.123.205";
static WORD g_nPort = 37777;
static char g_szUserName[64] = "admin";
static char g_szPasswd[64] = "wwzy123456";

static int nAlarmChn = 0;
static int nnLane = 0; 
static int nnParkingSpaceStatus = 0;
static DWORD  nPTS = 0;
static char CarNumber[32] = {};

static char mydata[4096], myurl[4096];	
static char snAlarmChn[20],snnLane[20],snPTS[50],snnParkingSpaceStatus[20];

void CALLBACK DisConnectFunc(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser);
void CALLBACK HaveReConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser);
int CALLBACK AnalyzerDataCallBack(LLONG lAnalyzerHandle, DWORD dwAlarmType, void* pAlarmInfo, BYTE *pBuffer, DWORD dwBufSize, LDWORD dwUser, int nSequence, void *reserved);
int CALLBACK AnalyzerDataCallBack1(LLONG lAnalyzerHandle, DWORD dwAlarmType, void* pAlarmInfo, BYTE *pBuffer, DWORD dwBufSize, LDWORD dwUser, int nSequence, void *reserved);
int put(const char* host, int port, const char* data, const char* url);

void InitTest()
{
	SDKInitFlag = CLIENT_Init(DisConnectFunc,0);
	if (SDKInitFlag == FALSE)
	{
		printf("Initialize SDK fail !\n");
	}
	else
	{
		printf("Initialize SDK succeed !\n");
	}
	
	CLIENT_SetAutoReconnect(&HaveReConnect,0);
	
	NET_DEVICEINFO_Ex stDevInfoEx = {0};
	int nError = 0;
	while (g_lLoginHandle == 0)
	{
		g_lLoginHandle = CLIENT_LoginEx2(g_szDevIp,g_nPort,g_szUserName,g_szPasswd,EM_LOGIN_SPEC_CAP_TCP,NULL,&stDevInfoEx,&nError);
		if (g_lLoginHandle == 0)
		{
			printf("CLIENT_LoginEx2 %s [%d] Failed! Last error[%x]\n",g_szDevIp,g_nPort,CLIENT_GetLastError());
		}
		else
		{
			printf("CLIENT_LoginEx2 %s [%d] Succeed! \n",g_szDevIp,g_nPort);
		}
	}
	
	sleep(1);
	printf("\n");
}

void RunTest()
{
	if (SDKInitFlag == FALSE)
	{
		return ;
	}
	if (g_lLoginHandle == 0)
	{
		return ;
	}

	LDWORD dwUser = 0;
	int nChannel = 0;	
	g_LRealLoadHandle = CLIENT_RealLoadPictureEx(g_lLoginHandle,nChannel,EVENT_IVS_ALL,FALSE,AnalyzerDataCallBack,dwUser,NULL);
	
	int nChannel1 = 1;	
	g_LRealLoadHandle1 = CLIENT_RealLoadPictureEx(g_lLoginHandle,nChannel1,EVENT_IVS_ALL,FALSE,AnalyzerDataCallBack1,dwUser,NULL);
	
	if (g_LRealLoadHandle == 0 || g_LRealLoadHandle1 == 0)
	{
		printf("CLIENT_RealLoadPictureEx Failed ! Last Error [%x]\n",CLIENT_GetLastError());
		return ;
	}
	else
	{
		printf("CLIENT_RealLoadPictureEx Succeed!\n");
	}
}

void EndTest()
{
	printf ("input any key to quit!\n");
	getchar();
	
	//stop the load picture alarm
	if (g_LRealLoadHandle != 0 && g_LRealLoadHandle1 != 0)
	{
		if (CLIENT_StopLoadPic(g_LRealLoadHandle) == FALSE || CLIENT_StopLoadPic(g_LRealLoadHandle1) == FALSE)
		{
			printf("CLIENT_StopLoadPic Failed! Last Error [%x]\n",CLIENT_GetLastError());
		}
		else
		{
			printf("CLIENT_StopLoadPic Succeed!\n");
			g_LRealLoadHandle = 0;
			g_LRealLoadHandle1 = 0;
		}
	}
	
	//log out the facility
	if (g_lLoginHandle != 0)
	{
		if (CLIENT_Logout(g_lLoginHandle) == FALSE)
		{
			printf("CLIENT_Logout Failed! Last Error [%x]\n",CLIENT_GetLastError());
		}
		else
		{
			printf("CLIENT_Logout Succeed!\n");
			g_lLoginHandle = 0;
		}
	}
	
	//clear init resource
	if (SDKInitFlag == TRUE)
	{
		CLIENT_Cleanup();
		SDKInitFlag = FALSE;
		printf("CLIENT_Cleanup Succeed!\n");
	}
	return;
}

int main ()
{
	InitTest();
	RunTest();
	EndTest();
	return 0;
}

void CALLBACK DisConnectFunc(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
{
	printf("Call DisConnectFunc\n");
	printf("lLoginID[0x%x]\n",lLoginID);
	if (pchDVRIP != NULL)
	{
		printf("pchDVRIP[%s]\n",pchDVRIP);
	}
	printf("nDVRPort[%d]\n",nDVRPort);
	printf("dwUser[%p]\n",dwUser);
	printf("\n");
	
}

void CALLBACK HaveReConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
{
	printf("Call HaveReConnect\n");
	printf("lLoginID[0x%x]\n",lLoginID);
	if (pchDVRIP != NULL)
	{
		printf("pchDVRIP[%s]\n",pchDVRIP);
	}
	printf("nDVRPort[%d]\n",nDVRPort);
	printf("dwUser[%p]\n",dwUser);
	printf("\n");
}

int CALLBACK AnalyzerDataCallBack(LLONG lAnalyzerHandle, DWORD dwAlarmType, void* pAlarmInfo, BYTE *pBuffer, DWORD dwBufSize, LDWORD dwUser, int nSequence, void *reserved)
{
	if (lAnalyzerHandle != g_LRealLoadHandle)
	{
		return 0;
	}
	
	{
		DEV_EVENT_TRAFFIC_TRAFFICCAR_INFO nstTrafficCar; 
		switch(dwAlarmType)
		{
			case EVENT_IVS_TRAFFIC_PARKINGSPACEPARKING:
				{
					printf("**************HaveCar Event!**************\n");
					DEV_EVENT_TRAFFIC_PARKINGSPACEPARKING_INFO *pStuInfo = (DEV_EVENT_TRAFFIC_PARKINGSPACEPARKING_INFO*)pAlarmInfo;
					
					nAlarmChn = pStuInfo->nChannelID;
					nnLane = pStuInfo->nLane;
					nPTS = pStuInfo->PTS;
					nstTrafficCar = pStuInfo->stTrafficCar;
					memcpy (CarNumber,nstTrafficCar.szPlateNumber,32);
					nnParkingSpaceStatus = pStuInfo->nParkingSpaceStatus; 
					
					printf("ChannelID-CarLocation[%d-%d]\n",nAlarmChn,nnLane);
					printf("FindTime[%d]\n",nPTS);
					printf("CarNumber[%s]\n",CarNumber);
					printf("ParkSpaceStatus[%d]\n",nnParkingSpaceStatus);

					sprintf(snAlarmChn,"%d",nAlarmChn);
   					sprintf(snnLane,"%d",nnLane);
   					sprintf(snPTS,"%d",nPTS);
    					sprintf(snnParkingSpaceStatus,"%d",nnParkingSpaceStatus);

    					memset(mydata, 0, 4096);
					strcat(mydata,"{");
					strcat(mydata,"\"car_port\": ");
					strcat(mydata, snnLane);
					strcat(mydata, ",\"car_channel\":");
					strcat(mydata,snAlarmChn);
					strcat(mydata, ",\"car_license\":");
					strcat(mydata, "\"");
					strcat(mydata, CarNumber);
					strcat(mydata, "#\"");
					strcat(mydata, ",\"find_time\":");
					strcat(mydata,snPTS);
					strcat(mydata, ",\"port_stauts\":");
					strcat(mydata, snnParkingSpaceStatus);
					strcat(mydata, ",\"camera_name\":");
					strcat(mydata,"\"camera_1\"");
					strcat(mydata, ",\"map_id\":");
					strcat(mydata, "1");
					strcat(mydata,"}");
					printf("\n%s\n",mydata);
    
    				    memset(myurl, 0, 4096);
				    strcat(myurl,"/cameras/");
				    strcat(myurl, "1");
				    strcat(myurl, "/");
				    strcat(myurl,"1/");
				    strcat(myurl, snAlarmChn);
				    strcat(myurl, "/");
				    strcat(myurl, snnLane);
				    strcat(myurl, " HTTP/1.1");
				     printf("\n%s\n",myurl);

				     int sockfd = put(IPSTR, PORT, mydata, myurl);

				    fd_set   t_set1;
				    FD_ZERO(&t_set1);
				    FD_SET(sockfd, &t_set1);

				    int h, i;
				    struct timeval  tv;
				    char buf[BUFSIZE];
				    while(1){
				        sleep(2);
				        tv.tv_sec= 0;
				        tv.tv_usec= 0;
				        h= 0;
				        printf("--------------->1");
				        h= select(sockfd +1, &t_set1, NULL, NULL, &tv);
				        printf("--------------->2");

				        if(h < 0) {
				            close(sockfd);
				            printf("Except appears when reading the data , the thread is stopped!\n");
				            return -1;
				        };

				        if(h > 0){
				            memset(buf, 0, 4096);
				            i= read(sockfd, buf, 4095);
				            if(i==0){
				                close(sockfd);
				                printf("The distance is closed when reading the data , the thread is stopped!\n");
				                return -1;
				            }

				            printf("%s\n", buf);
				        }
				    }
				    close(sockfd);
				}
				break;
			
			case EVENT_IVS_TRAFFIC_PARKINGSPACENOPARKING:
				{
					printf("**************NoCar Event!**************\n");
					DEV_EVENT_TRAFFIC_PARKINGSPACENOPARKING_INFO *pStuInfo = (DEV_EVENT_TRAFFIC_PARKINGSPACENOPARKING_INFO*)pAlarmInfo;
					
					nAlarmChn = pStuInfo->nChannelID;
					nnLane = pStuInfo->nLane;
					nPTS = pStuInfo->PTS;
					nstTrafficCar = pStuInfo->stTrafficCar;
					memcpy (CarNumber,nstTrafficCar.szPlateNumber,32);
					nnParkingSpaceStatus = pStuInfo->nParkingSpaceStatus; 
					
					printf("ChannelID-CarLocation[%d-%d]\n",nAlarmChn,nnLane);
					printf("FindTime[%d]\n",nPTS);
					printf("CarNumber[%s]\n",CarNumber);
					printf("ParkSpaceStatus[%d]\n",nnParkingSpaceStatus);

					sprintf(snAlarmChn,"%d",nAlarmChn);
   					sprintf(snnLane,"%d",nnLane);
   					sprintf(snPTS,"%d",nPTS);
    					sprintf(snnParkingSpaceStatus,"%d",nnParkingSpaceStatus);

    					memset(mydata, 0, 4096);
					strcat(mydata,"{");
					strcat(mydata,"\"car_port\": ");
					strcat(mydata, snnLane);
					strcat(mydata, ",\"car_channel\":");
					strcat(mydata,snAlarmChn);
					strcat(mydata, ",\"car_license\":");
					strcat(mydata, "\"");
					strcat(mydata, CarNumber);
					strcat(mydata, "#\"");
					strcat(mydata, ",\"find_time\":");
					strcat(mydata,snPTS);
					strcat(mydata, ",\"port_stauts\":");
					strcat(mydata, snnParkingSpaceStatus);
					strcat(mydata, ",\"camera_name\":");
					strcat(mydata,"\"camera_1\"");
					strcat(mydata, ",\"map_id\":");
					strcat(mydata, "1");
					strcat(mydata,"}");
					printf("\n%s\n",mydata);
    
				    memset(myurl, 0, 4096);
				    strcat(myurl,"/cameras/");
				    strcat(myurl, "1");
				    strcat(myurl, "/");
				    strcat(myurl,"1/");
				    strcat(myurl, snAlarmChn);
				    strcat(myurl, "/");
				    strcat(myurl, snnLane);
				    strcat(myurl, " HTTP/1.1");
				    printf("\n%s\n",myurl);

				     int sockfd = put(IPSTR, PORT, mydata, myurl);

				    fd_set   t_set1;
				    FD_ZERO(&t_set1);
				    FD_SET(sockfd, &t_set1);

				    int h, i;
				    struct timeval  tv;
				    char buf[BUFSIZE];
				    while(1){
				        sleep(2);
				        tv.tv_sec= 0;
				        tv.tv_usec= 0;
				        h= 0;
				        printf("--------------->1");
				        h= select(sockfd +1, &t_set1, NULL, NULL, &tv);
				        printf("--------------->2");

				        if(h < 0) {
				            close(sockfd);
				            printf("Except appears when reading the data , the thread is stopped!\n");
				            return -1;
				        };

				        if(h > 0){
				            memset(buf, 0, 4096);
				            i= read(sockfd, buf, 4095);
				            if(i==0){
				                close(sockfd);
				                printf("The distance is closed when reading the data , the thread is stopped!\n");
				                return -1;
				            }

				            printf("%s\n", buf);
				        }
				    }
				    close(sockfd);
                                }
				break;
			
			default:
				printf("other event type [%d]\n",dwAlarmType);	
				break;
		}
	}
}

int CALLBACK AnalyzerDataCallBack1(LLONG lAnalyzerHandle, DWORD dwAlarmType, void* pAlarmInfo, BYTE *pBuffer, DWORD dwBufSize, LDWORD dwUser, int nSequence, void *reserved)
{
	if (lAnalyzerHandle != g_LRealLoadHandle1)
	{
		return 0;
	}
	
	{
		 DEV_EVENT_TRAFFIC_TRAFFICCAR_INFO nstTrafficCar; 
		switch(dwAlarmType)
		{
			case EVENT_IVS_TRAFFIC_PARKINGSPACEPARKING:
				{
					printf("**************HaveCar Event!**************\n");
					DEV_EVENT_TRAFFIC_PARKINGSPACEPARKING_INFO *pStuInfo = (DEV_EVENT_TRAFFIC_PARKINGSPACEPARKING_INFO*)pAlarmInfo;
					
					nAlarmChn = pStuInfo->nChannelID;
					nnLane = pStuInfo->nLane;
					nPTS = pStuInfo->PTS;
					nstTrafficCar = pStuInfo->stTrafficCar;
					memcpy (CarNumber,nstTrafficCar.szPlateNumber,32);
					nnParkingSpaceStatus = pStuInfo->nParkingSpaceStatus; 
					
					printf("ChannelID-CarLocation[%d-%d]\n",nAlarmChn,nnLane);
					printf("FindTime[%d]\n",nPTS);
					printf("CarNumber[%s]\n",CarNumber);
					printf("ParkSpaceStatus[%d]\n",nnParkingSpaceStatus);

					sprintf(snAlarmChn,"%d",nAlarmChn);
   					sprintf(snnLane,"%d",nnLane);
   					sprintf(snPTS,"%d",nPTS);
    					sprintf(snnParkingSpaceStatus,"%d",nnParkingSpaceStatus);

    					memset(mydata, 0, 4096);
					strcat(mydata,"{");
					strcat(mydata,"\"car_port\": ");
					strcat(mydata, snnLane);
					strcat(mydata, ",\"car_channel\":");
					strcat(mydata,snAlarmChn);
					strcat(mydata, ",\"car_license\":");
					strcat(mydata, "\"");
					strcat(mydata, CarNumber);
					strcat(mydata, "#\"");
					strcat(mydata, ",\"find_time\":");
					strcat(mydata,snPTS);
					strcat(mydata, ",\"port_stauts\":");
					strcat(mydata, snnParkingSpaceStatus);
					strcat(mydata, ",\"camera_name\":");
					strcat(mydata,"\"camera_1\"");
					strcat(mydata, ",\"map_id\":");
					strcat(mydata, "1");
					strcat(mydata,"}");
					printf("\n%s\n",mydata);
    
				    memset(myurl, 0, 4096);
				    strcat(myurl,"/cameras/");
				    strcat(myurl, "1");
				    strcat(myurl, "/");
				    strcat(myurl,"1/");
				    strcat(myurl, snAlarmChn);
				    strcat(myurl, "/");
				    strcat(myurl, snnLane);
				    strcat(myurl, " HTTP/1.1");
				     printf("\n%s\n",myurl);

				     int sockfd = put(IPSTR, PORT, mydata, myurl);

				    fd_set   t_set1;
				    FD_ZERO(&t_set1);
				    FD_SET(sockfd, &t_set1);

				    int h, i;
				    struct timeval  tv;
				    char buf[BUFSIZE];
				    while(1){
				        sleep(2);
				        tv.tv_sec= 0;
				        tv.tv_usec= 0;
				        h= 0;
				        printf("--------------->1");
				        h= select(sockfd +1, &t_set1, NULL, NULL, &tv);
				        printf("--------------->2");

				        if(h < 0) {
				            close(sockfd);
				            printf("Except appears when reading the data , the thread is stopped!\n");
				            return -1;
				        };

				        if(h > 0){
				            memset(buf, 0, 4096);
				            i= read(sockfd, buf, 4095);
				            if(i==0){
				                close(sockfd);
				                printf("The distance is closed when reading the data , the thread is stopped!\n");
				                return -1;
				            }

				            printf("%s\n", buf);
				        }
				    }
				    close(sockfd);
				}
				break;
			
			case EVENT_IVS_TRAFFIC_PARKINGSPACENOPARKING:
				{
					printf("**************NoCar Event!**************\n");
					DEV_EVENT_TRAFFIC_PARKINGSPACENOPARKING_INFO *pStuInfo = (DEV_EVENT_TRAFFIC_PARKINGSPACENOPARKING_INFO*)pAlarmInfo;
					
					nAlarmChn = pStuInfo->nChannelID;
					nnLane = pStuInfo->nLane;
					nPTS = pStuInfo->PTS;
					nstTrafficCar = pStuInfo->stTrafficCar;
					memcpy (CarNumber,nstTrafficCar.szPlateNumber,32);
					nnParkingSpaceStatus = pStuInfo->nParkingSpaceStatus; 
					
					printf("ChannelID-CarLocation[%d-%d]\n",nAlarmChn,nnLane);
					printf("FindTime[%d]\n",nPTS);
					printf("CarNumber[%s]\n",CarNumber);
					printf("ParkSpaceStatus[%d]\n",nnParkingSpaceStatus);

					sprintf(snAlarmChn,"%d",nAlarmChn);
   					sprintf(snnLane,"%d",nnLane);
   					sprintf(snPTS,"%d",nPTS);
    					sprintf(snnParkingSpaceStatus,"%d",nnParkingSpaceStatus);

    					memset(mydata, 0, 4096);
					strcat(mydata,"{");
					strcat(mydata,"\"car_port\": ");
					strcat(mydata, snnLane);
					strcat(mydata, ",\"car_channel\":");
					strcat(mydata,snAlarmChn);
					strcat(mydata, ",\"car_license\":");
					strcat(mydata, "\"");
					strcat(mydata, CarNumber);
					strcat(mydata, "#\"");
					strcat(mydata, ",\"find_time\":");
					strcat(mydata,snPTS);
					strcat(mydata, ",\"port_stauts\":");
					strcat(mydata, snnParkingSpaceStatus);
					strcat(mydata, ",\"camera_name\":");
					strcat(mydata,"\"camera_1\"");
					strcat(mydata, ",\"map_id\":");
					strcat(mydata, "1");
					strcat(mydata,"}");
					printf("\n%s\n",mydata);
    
				    memset(myurl, 0, 4096);
				    strcat(myurl,"/cameras/");
				    strcat(myurl, "1");
				    strcat(myurl, "/");
				    strcat(myurl,"1/");
				    strcat(myurl, snAlarmChn);
				    strcat(myurl, "/");
				    strcat(myurl, snnLane);
				    strcat(myurl, " HTTP/1.1");
				     printf("\n%s\n",myurl);

				     int sockfd = put(IPSTR, PORT, mydata, myurl);

				    fd_set   t_set1;
				    FD_ZERO(&t_set1);
				    FD_SET(sockfd, &t_set1);

				    int h, i;
				    struct timeval  tv;
				    char buf[BUFSIZE];
				    while(1){
				        sleep(2);
				        tv.tv_sec= 0;
				        tv.tv_usec= 0;
				        h= 0;
				        printf("--------------->1");
				        h= select(sockfd +1, &t_set1, NULL, NULL, &tv);
				        printf("--------------->2");

				        if(h < 0) {
				            close(sockfd);
				            printf("Except appears when reading the data , the thread is stopped!\n");
				            return -1;
				        };

				        if(h > 0){
				            memset(buf, 0, 4096);
				            i= read(sockfd, buf, 4095);
				            if(i==0){
				                close(sockfd);
				                printf("The distance is closed when reading the data , the thread is stopped!\n");
				                return -1;
				            }

				            printf("%s\n", buf);
				        }
				    }
				    close(sockfd);
                                }
				break;
			
			default:
				printf("other event type [%d]\n",dwAlarmType);	
				break;
		}
	}
}

int put(const char* host, int port, const char* data, const char* url)
{
				    int sockfd, ret;
				    struct sockaddr_in servaddr;
				    char str1[4096], str2[4096], *str;
				    socklen_t len;

				    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
				        printf("Fail to create connection---socket error!\n");
				        exit(0);
				    };

				    bzero(&servaddr,sizeof(servaddr));
				    servaddr.sin_family = AF_INET;
				    servaddr.sin_port = htons(port);
				    if(inet_pton(AF_INET, host, &servaddr.sin_addr) <= 0 ){
				        printf("Fail to create connection---inet_pton error!\n");
				        exit(0);
				    };

				    if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){
				        printf("Connect Failed,connect error!\n");
				        exit(0);
				    }
				    printf("Connect Succeed!\n");

				    memset(str2, 0, 4096);
				    strcat(str2, data);
				    str=(char*)malloc(128);
				    len =strlen(str2);
				    sprintf(str,"%d", len);

				    memset(str1, 0, 4096);
				    strcat(str1,"PUT ");
				    strcat(str1, url);
				    strcat(str1, "\n");
				    strcat(str1,"Host: ");
				    strcat(str1, host);
				    strcat(str1, ":5000");
				    strcat(str1, " \n");
				    strcat(str1,"Content-Type: application/json\n");
				    strcat(str1,"Content-Length: ");
				    strcat(str1, str);
				    strcat(str1,"\n\n");

				    strcat(str1, str2);
				    strcat(str1,"\r\n\r\n");
				    printf("%s\n",str1);

				    ret = write(sockfd,str1,strlen(str1));

				    return sockfd;
}









